package com.easylinkin.linkappapi.progress.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.bases.redis.util.RedisUtil;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.common.utils.BusinessSerialNoUtil;
import com.easylinkin.linkappapi.common.utils.async.AsyncUtil;
import com.easylinkin.linkappapi.common.utils.excel.ExcelReadUtil;
import com.easylinkin.linkappapi.lobar.dto.excel.ExcelResultDTO;
import com.easylinkin.linkappapi.lobar.dto.excel.ExcelResultDetailDTO;
import com.easylinkin.linkappapi.progress.entity.ProgressInfo;
import com.easylinkin.linkappapi.progress.entity.ProgressIntegrateRef;
import com.easylinkin.linkappapi.progress.entity.dto.ProgressInfoDTO;
import com.easylinkin.linkappapi.progress.entity.dto.ScreenProgressInfoDTO;
import com.easylinkin.linkappapi.progress.entity.vo.ProgressInfoVo;
import com.easylinkin.linkappapi.progress.entity.vo.ProgressIntegrateRefVo;
import com.easylinkin.linkappapi.progress.mapper.ProgressInfoMapper;
import com.easylinkin.linkappapi.progress.mapper.ProgressIntegrateRefMapper;
import com.easylinkin.linkappapi.progress.service.ProgressInfoService;
import com.easylinkin.linkappapi.progress.service.ProgressIntegrateRefService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
//import com.easylinkin.linkappapi.systemsettings.entity.BimIntegrateItem;
//import com.easylinkin.linkappapi.systemsettings.entity.SystemBimConfig;
//import com.easylinkin.linkappapi.systemsettings.entity.dto.BimIntegrateItemDTO;
//import com.easylinkin.linkappapi.systemsettings.entity.vo.BimIntegrateItemVo;
//import com.easylinkin.linkappapi.systemsettings.mapper.BimIntegrateItemMapper;
//import com.easylinkin.linkappapi.systemsettings.mapper.SystemBimConfigMapper;
//import com.easylinkin.linkappapi.systemsettings.service.BimIntegrateItemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ProgressInfo表服务实现类
 *
 * @author zhengwen
 * @date 2023/11/13
 */
@Slf4j
@Service("appProgressInfoService")
public class ProgressInfoServiceImpl extends ServiceImpl
        <ProgressInfoMapper, ProgressInfo> implements ProgressInfoService {
    @Resource
    private CommonService commonService;

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ProgressIntegrateRefMapper progressIntegrateRefMapper;

    @Resource(type = ProgressIntegrateRefService.class)
    private ProgressIntegrateRefService progressIntegrateRefService;

//    @Resource
//    private BimIntegrateItemMapper bimIntegrateItemMapper;
//
//    @Resource
//    private BimIntegrateItemService bimIntegrateItemService;
//
//    @Resource
//    private SystemBimConfigMapper systemBimConfigMapper;

    private String progressInfoKey = "progressInfoKey";

    @Override
    public boolean removeById(Serializable id) {
        return super.update().set("deleted_", id).eq("id_", id).update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(List<Long> idList) {
        //级连删除
        idList.forEach(id -> {
            //查询
            ProgressInfo progressInfo = baseMapper.getOneById(id);
            if (progressInfo != null) {
                List<ProgressInfo> taskList = new ArrayList<>();
                //判断类型
                Integer type = progressInfo.getType();
                if (type == 1) {
                    //计划
                    //查询计划任务
                    QueryWrapper<ProgressInfo> qw = new QueryWrapper<>();
                    qw.likeRight("parent_ids_", progressInfo.getParentIds() + progressInfo.getId() + ",");
                    taskList = baseMapper.selectList(qw);
                    //删除计划
                    baseMapper.deleteById(id);
                } else {
                    //查询计划任务
                    QueryWrapper<ProgressInfo> qw = new QueryWrapper<>();
                    qw.likeRight("parent_ids_", progressInfo.getParentIds() + progressInfo.getId() + ",");
                    taskList = baseMapper.selectList(qw);
                    taskList.add(progressInfo);
                }
                //删除任务
                if (CollectionUtil.isNotEmpty(taskList)) {
                    taskList.forEach(task -> {
                        Long taskId = task.getId();
                        //删除任务模型关联关系
                        QueryWrapper<ProgressIntegrateRef> refQw = new QueryWrapper<>();
                        refQw.eq("progress_id_", taskId);
                        progressIntegrateRefMapper.delete(refQw);
                        //删除任务
                        baseMapper.deleteById(taskId);
                    });
                }

            }
        });

        return true;
    }


    @Override
    public boolean saveOne(ProgressInfo appProgressInfo) {
        commonService.setCreateAndModifyInfo(appProgressInfo);

        validParamRequired(appProgressInfo);
        validRepeat(appProgressInfo);
        validParamFormat(appProgressInfo);
        return save(appProgressInfo);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOne(ProgressInfo appProgressInfo) {
        Assert.notNull(appProgressInfo.getId(), "id不能为空");
        commonService.setModifyInfo(appProgressInfo);

        validRepeat(appProgressInfo);
        validParamFormat(appProgressInfo);
        return updateById(appProgressInfo);
    }

    @Override
    public IPage<ProgressInfo> selectPage(Page page, ProgressInfo appProgressInfo) {
        return baseMapper.selectPage(page, appProgressInfo);
    }

    @Override
    public void export(ProgressInfo appProgressInfo, HttpServletRequest request, HttpServletResponse
            response) {

    }

    @Override
    public RestMessage addProgress(ProgressInfoVo progressInfoVo) {
        LinkappUser linkappUser = linkappUserContextProducer.getCurrent();
        Assert.notNull(linkappUser, "用户登录信息为空");
        Assert.notNull(linkappUser.getTenantId(), "用户租户id为空");

        progressInfoVo.setTenantId(linkappUser.getTenantId());

        Assert.notNull(progressInfoVo, "参数为空");
        Integer type = progressInfoVo.getType();
        Assert.notNull(type, "类型为空");

        ProgressInfo appProgressInfo = new ProgressInfo();
        BeanUtil.copyProperties(progressInfoVo, appProgressInfo, CopyOptions.create().ignoreNullValue());
        //校验参数
        validParamRequired(appProgressInfo);
        //校验重复
        validRepeat(appProgressInfo);

        //进度计划
        if (type == 1) {
            String cacheKey = progressInfoKey + ":progressInfo";
            String code = BusinessSerialNoUtil.genSeqCode(redisUtil, "JH", "", 4);
            appProgressInfo.setCode(code);
            appProgressInfo.setParentId(0L);
            appProgressInfo.setParentIds("0,");
        } else {
            //进度任务
            Long parentId = appProgressInfo.getParentId();
            Assert.notNull(parentId, "父id为空");
            //查询父级
            ProgressInfo parentProgress = baseMapper.selectById(parentId);
            Assert.notNull(parentProgress, "父级数据不存在");

            appProgressInfo.setParentIds(parentProgress.getParentIds() + parentId + ",");

            //校验父级类型
            Integer parentType = parentProgress.getType();
            if (parentType == 2) {
                //父级为任务,需要校验是否关联了模型
                QueryWrapper<ProgressIntegrateRef> qw = new QueryWrapper<>();
                qw.eq("progress_id_", parentId);
                int count = progressIntegrateRefMapper.selectCount(qw);
                Assert.isTrue(count == 0, "父级已经关联模型，不能增加下级任务");
            }
        }

        //设置基础信息
        appProgressInfo.setTenantId(linkappUser.getTenantId());
        commonService.setCreateAndModifyInfo(appProgressInfo);
        baseMapper.insert(appProgressInfo);

        return RestBuilders.successBuilder().build();
    }

    @Override
    public RestMessage progressDetail(Long id) {
        ProgressInfo appProgressInfo = baseMapper.selectById(id);
        Assert.notNull(appProgressInfo, "数据不存在");
        ProgressInfoDTO progressInfoDTO = new ProgressInfoDTO();
        BeanUtil.copyProperties(appProgressInfo, progressInfoDTO, CopyOptions.create().ignoreNullValue());

        return RestBuilders.successBuilder().data(progressInfoDTO).build();
    }

    @Override
    public IPage<ProgressInfoDTO> selectDtoPage(Page page, ProgressInfoVo progressInfoVo) {
        LinkappUser linkappUser = linkappUserContextProducer.getCurrent();
        Assert.notNull(linkappUser, "用户登录信息为空");
        Assert.notNull(linkappUser.getTenantId(), "用户租户id为空");
        progressInfoVo.setTenantId(linkappUser.getTenantId());

        Long paramId = progressInfoVo.getId();
        if (paramId != null) {
            ProgressInfo progressInfo = baseMapper.getOneById(paramId);
            if (progressInfo != null) {
                progressInfoVo.setParentIds(progressInfo.getParentIds() + progressInfo.getId() + ",");
            }
        }

        IPage<ProgressInfoDTO> iPage = baseMapper.selectDtoPage(page, progressInfoVo);
        List<ProgressInfoDTO> dtoList = iPage.getRecords();
        if (CollectionUtil.isNotEmpty(dtoList)) {
            //循环查询模型关联数量太慢，改为批量查询
            List<Long> idList = dtoList.stream().map(ProgressInfoDTO::getId).collect(Collectors.toList());
            QueryWrapper<ProgressIntegrateRef> qw = new QueryWrapper<>();
            qw.select("progress_id_ ,count(*) as num ");
            qw.in("progress_id_", idList);
            qw.groupBy("progress_id_");

            Map<Long,Long> mp;
            List<Map<String, Object>> mapList = progressIntegrateRefMapper.selectMaps(qw);
            if (CollectionUtil.isNotEmpty(mapList)){
                mp = mapList.stream().collect(Collectors.toMap(map -> (Long) map.get("progress_id_"), map -> map.get("num") == null?0:(Long)map.get("num")));
            } else {
                mp = new HashMap<>();
            }
            dtoList.forEach(dto -> {
                Integer type = dto.getType();
                if (type == 2) {
                    Long id = dto.getId();
                    Long count = mp.get(id);
//                    if (count != null && count > 0) {
//                        dto.setJoinModel(true);
//                    }
                    /*//进度任务
                    Long id = dto.getId();
                    //查询模型关联关系
                    QueryWrapper<ProgressIntegrateRef> qw = new QueryWrapper<>();
                    qw.eq("progress_id_", id);
                    int count = progressIntegrateRefMapper.selectCount(qw);
                    if (count > 0) {
                        dto.setJoinModel(true);
                    }*/
                }
            });
        }

        return iPage;
    }

    @Override
    public RestMessage updateProgress(ProgressInfoVo progressInfoVo) {
        //查询
        Long id = progressInfoVo.getId();
        ProgressInfo dbProgress = baseMapper.selectById(id);
        Assert.notNull(dbProgress, "数据不存在");

        //转换
        ProgressInfo progressInfo = new ProgressInfo();
        progressInfo.setTenantId(dbProgress.getTenantId());
        BeanUtil.copyProperties(progressInfoVo, progressInfo, CopyOptions.create().ignoreNullValue());

        //校验
        validParamRequired(progressInfo);

        //校验重复
        validRepeat(progressInfo);

        commonService.setModifyInfo(progressInfo);

        baseMapper.updateById(progressInfo);

        return RestBuilders.successBuilder().build();
    }

    @Override
    public RestMessage joinModel(ProgressInfoVo progressInfoVo) {
        //进度计划id
        Long progressPlanId = progressInfoVo.getProgressPlanId();
        Assert.notNull(progressPlanId, "进度计划id为空");

        //进度任务
        Long id = progressInfoVo.getId();
        ProgressInfo progressInfo = baseMapper.selectById(id);
        Assert.notNull(progressInfo, "数据不存在");

//        //模型传参list
//        List<BimIntegrateItem> newItemList = progressInfoVo.getIntegrateList();
//
//        List<BimIntegrateItem> successIntegrateList = new ArrayList<>();
//        List<BimIntegrateItem> failIntegrateList = new ArrayList<>();
        List<ProgressIntegrateRef> progressIntegrateRefList = new ArrayList<>();

//        // 重新绑定
//        if (CollectionUtil.isEmpty(newItemList)){
//            // 删全部
//            LambdaQueryWrapper<ProgressIntegrateRef> delQw = new LambdaQueryWrapper<ProgressIntegrateRef>()
//                    .eq(ProgressIntegrateRef::getProgressId, id);
//            progressIntegrateRefMapper.delete(delQw);
//
//        } else {
            // 2024-09，数据库不存了，直接用传入的
            // 查询模型
            // List<String> resourceIdList = bimIntegrateList.stream().map(BimIntegrateItem::getResourceId).filter(StringUtil::isNotBlank).collect(Collectors.toList());
            // LambdaQueryWrapper<BimIntegrateItem> bimIntegrateItemWrapper = new LambdaQueryWrapper<>();
            // bimIntegrateItemWrapper.in(BimIntegrateItem::getResourceId, resourceIdList)
            //         .select(BimIntegrateItem::getName, BimIntegrateItem::getResourceId);
            // List<BimIntegrateItem> bimIntegrateItemList = bimIntegrateItemMapper.selectList(bimIntegrateItemWrapper);
            // Assert.notEmpty(bimIntegrateItemList, "关联模型不存在");

            // 旧数据
            LambdaQueryWrapper<ProgressIntegrateRef> oldQw = new LambdaQueryWrapper<ProgressIntegrateRef>()
                    .eq(ProgressIntegrateRef::getProgressId, id)
                    .select(ProgressIntegrateRef::getResourceId);
            Set<String> oldResourceIdSet = progressIntegrateRefMapper.selectList(oldQw)
                    .stream()
                    .map(ProgressIntegrateRef::getResourceId).collect(Collectors.toSet());

            // 查询计划里的所有任务
            LambdaQueryWrapper<ProgressInfo> floorWrapper = new LambdaQueryWrapper<ProgressInfo>()
                    .eq(ProgressInfo::getType,2)
                    .likeRight(ProgressInfo::getParentIds, "0,"+progressPlanId)
                    .select(ProgressInfo::getId);
            List<Long> progressIds = baseMapper.selectList(floorWrapper).stream().map(ProgressInfo::getId).collect(Collectors.toList());

            // 被别人关联
            LambdaQueryWrapper<ProgressIntegrateRef> progressIntegrateRefWrapper = new LambdaQueryWrapper<ProgressIntegrateRef>()
                    .in(ProgressIntegrateRef::getProgressId, progressIds)
                    .ne(ProgressIntegrateRef::getProgressId, id)
                    .select(ProgressIntegrateRef::getResourceId);
            Set<String> joinedResourceIdSet = progressIntegrateRefMapper.selectList(progressIntegrateRefWrapper)
                    .stream()
                    .map(ProgressIntegrateRef::getResourceId)
                    .collect(Collectors.toSet());

            // 一次反射获取创建、更新
            ProgressIntegrateRef temp = new ProgressIntegrateRef();
            commonService.setCreateAndModifyInfo(temp);

//            for (BimIntegrateItem integrateItem : newItemList) {
//                String resourceId = integrateItem.getResourceId();
//                if (oldResourceIdSet.contains(resourceId)){
//                    // 已存在，不用删除
//                    oldResourceIdSet.remove(resourceId);
//                } else if(joinedResourceIdSet.contains(resourceId)) {
//                    // 已经被绑定，加入失败列表
//                    failIntegrateList.add(integrateItem);
//                } else {
//                    // 保存绑定关系
//                    ProgressIntegrateRef ref = new ProgressIntegrateRef();
//                    ref.setResourceId(integrateItem.getResourceId());
//                    ref.setProgressId(id);
//                    ref.setProgressPlanId(progressPlanId);
//                    ref.setCreateTime(temp.getCreateTime());
//                    ref.setCreator(temp.getCreator());
//                    ref.setModifyTime(temp.getModifyTime());
//                    ref.setModifier(temp.getModifier());
//                    progressIntegrateRefList.add(ref);
//                    successIntegrateList.add(integrateItem);
//                }
//            }

//            // 剩余的删除
//            if (!oldResourceIdSet.isEmpty()){
//                LambdaQueryWrapper<ProgressIntegrateRef> delQw = new LambdaQueryWrapper<ProgressIntegrateRef>()
//                        .in(ProgressIntegrateRef::getResourceId, oldResourceIdSet);
//                progressIntegrateRefMapper.delete(delQw);
//            }
//            // 多的新增
//            if (!progressIntegrateRefList.isEmpty()) {
//                progressIntegrateRefService.saveBatch(progressIntegrateRefList);
//            }
//
//        }
//
//        // 处理出参
//        progressInfoVo.setSuccessIntegrateList(successIntegrateList);
//        progressInfoVo.setFailIntegrateList(failIntegrateList);
//        progressInfoVo.setIntegrateList(null);

        return RestBuilders.successBuilder().data(progressInfoVo).build();
    }

    @Override
    public List<ProgressIntegrateRefVo> getJoinModel(Long progressId) {
        //查询当前登陆用户
        LinkappUser linkappUser = linkappUserContextProducer.getCurrent();
        Assert.notNull(linkappUser, "用户登录信息为空");
        String bimfaceId = null;
        //获取当前用户所属项目
        String tenantId = linkappUser.getTenantId();
        if (StringUtils.isNotBlank(tenantId)){
//            //查询当前项目配置的bimfaceId
//            QueryWrapper<SystemBimConfig> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("tenant_id_",tenantId);
//            SystemBimConfig systemBimConfig = systemBimConfigMapper.selectOne(queryWrapper);
//            if (systemBimConfig != null){
//                bimfaceId = systemBimConfig.getIntegrateId();
//            }
        }
        if (StringUtils.isBlank(bimfaceId)){
            throw new BusinessException("请先配置bimId");
        }
        return progressIntegrateRefMapper.selectVoByProcessId(progressId,bimfaceId);
    }

    @Override
    public RestMessage getProgressModelTree(ProgressInfoVo progressInfoVo) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //查询
        Long id = progressInfoVo.getId();
        //进度计划id
        Long progressPlanId = progressInfoVo.getProgressPlanId();
        Assert.notNull(progressPlanId, "进度计划id为空");
        //进度信息
        ProgressInfo progressInfo = baseMapper.selectById(id);
        Assert.notNull(progressInfo, "数据不存在");

//        //查询模型树
//        List<BimIntegrateItemDTO> modelTreeDtoList = new ArrayList<>();
//        BimIntegrateItemVo bimIntegrateItemVo = new BimIntegrateItemVo();
//        bimIntegrateItemVo.setStart(0);
//        bimIntegrateItemVo.setEnd(8);
//        RestMessage modelTreeRestMsg = bimIntegrateItemService.getIntegrateResourceTree(bimIntegrateItemVo);
//        if (modelTreeRestMsg.isSuccess()) {
//            List<BimIntegrateItem> modelTreeList = modelTreeRestMsg.getData();
//            if (CollectionUtil.isNotEmpty(modelTreeList)) {
//                //element类型，查询关联关系
//                //modelTreeList过滤type=element，把resourceId转化为List<String>
//                List<String> resourceIdList = modelTreeList.stream().filter(modelTree -> "element".equals(modelTree.getType())).map(BimIntegrateItem::getResourceId).collect(Collectors.toList());
//                //查询我绑定的
//                List<String> myBindList = queryMyBindList(id, resourceIdList);
//                //查询被别人绑定的(20231207增加计划内不重复绑定)
//                List<String> otherJoinList = queryOtherJoinList(id, resourceIdList, progressPlanId);
//
//                modelTreeList.forEach(modelTree -> {
//                    BimIntegrateItemDTO dto = new BimIntegrateItemDTO();
//                    BeanUtil.copyProperties(modelTree, dto, CopyOptions.create().ignoreNullValue());
//                    String type = modelTree.getType();
//                    if ("element".equals(type)) {
//                        //element类型
//                        //处理我绑定的
//                        String resourceId = modelTree.getResourceId();
//                        if (myBindList.contains(resourceId)) {
//                            dto.setMyBind(true);
//                        } else {
//                            dto.setMyBind(false);
//                        }
//
//                        //查询被别人绑定的
//                        if (otherJoinList.contains(resourceId)) {
//                            dto.setJoined(true);
//                        } else {
//                            dto.setJoined(false);
//                        }
//                    }
//                    modelTreeDtoList.add(dto);
//                });
//            }
//        }
//        stopWatch.stop();
//        log.info("查询模型树耗时：{}s", stopWatch.getTotalTimeMillis());
//        return RestBuilders.successBuilder().data(modelTreeDtoList).build();
        return RestBuilders.successBuilder().data(null).build();
    }

    @Override
    public RestMessage getProgressModel(ProgressInfoVo progressInfoVo) {

        //进度计划id
        Long progressPlanId = progressInfoVo.getProgressPlanId();
        Assert.notNull(progressPlanId, "进度计划id为空");

        //进度任务id
        Long id = progressInfoVo.getId();
        ProgressInfo progressInfo = baseMapper.selectById(id);
        Assert.notNull(progressInfo, "数据不存在");

        // 查询计划里的所有任务
        LambdaQueryWrapper<ProgressInfo> floorWrapper = new LambdaQueryWrapper<ProgressInfo>()
                .eq(ProgressInfo::getType,2)
                .likeRight(ProgressInfo::getParentIds, "0,"+progressPlanId)
                .select(ProgressInfo::getId);
        List<ProgressInfo> progressInfos = baseMapper.selectList(floorWrapper);
        List<Long> progressIds = progressInfos.stream().map(ProgressInfo::getId).collect(Collectors.toList());

        // 被自己关联
        LambdaQueryWrapper<ProgressIntegrateRef> progressIntegrateRefWrapper1 = new LambdaQueryWrapper<ProgressIntegrateRef>()
                .eq(ProgressIntegrateRef::getProgressId, id)
                .select(ProgressIntegrateRef::getResourceId);
        List<ProgressIntegrateRef> floorIntegrateRefs1 = progressIntegrateRefMapper.selectList(progressIntegrateRefWrapper1);
        List<String> myBindList = floorIntegrateRefs1.stream().map(ProgressIntegrateRef::getResourceId).collect(Collectors.toList());
        // 被别人关联
        LambdaQueryWrapper<ProgressIntegrateRef> progressIntegrateRefWrapper2 = new LambdaQueryWrapper<ProgressIntegrateRef>()
                .in(ProgressIntegrateRef::getProgressId, progressIds)
                .ne(ProgressIntegrateRef::getProgressId, id)
                .select(ProgressIntegrateRef::getResourceId);
        List<ProgressIntegrateRef> floorIntegrateRefs2 = progressIntegrateRefMapper.selectList(progressIntegrateRefWrapper2);
        List<String> joinedList = floorIntegrateRefs2.stream().map(ProgressIntegrateRef::getResourceId).collect(Collectors.toList());

        // 结果
        HashMap<String, Object> result = new HashMap<>();
        result.put("myBindList", myBindList);
        result.put("joinedList", joinedList);
        return RestBuilders.successBuilder().data(result).build();
    }

    /**
     * 查询其他进度绑定的
     *
     * @param id             进度任务id
     * @param resourceIdList 资源id集合
     * @param progressPlanId 进度计划id
     * @return 资源id集合
     */
    private List<String> queryOtherJoinList(Long id, List<String> resourceIdList, Long progressPlanId) {
        QueryWrapper<ProgressIntegrateRef> qw = new QueryWrapper<>();
        //20231207增加计划内不能重复绑定
        qw.eq("progress_plan_id_", progressPlanId);
        qw.ne("progress_id_", id);
        qw.in("resource_id_", resourceIdList);
        List<ProgressIntegrateRef> refList = progressIntegrateRefMapper.selectList(qw);
        List<String> myBindList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(refList)) {
            myBindList = refList.stream().map(ProgressIntegrateRef::getResourceId).collect(Collectors.toList());
        }
        return myBindList;
    }

    /**
     * 查询当前进度任务绑定的
     *
     * @param id             进度任务id
     * @param resourceIdList 资源id集合
     * @return 资源id集合
     */
    private List<String> queryMyBindList(Long id, List<String> resourceIdList) {
        QueryWrapper<ProgressIntegrateRef> qw = new QueryWrapper<>();
        qw.eq("progress_id_", id);
        qw.in("resource_id_", resourceIdList);
        List<ProgressIntegrateRef> refList = progressIntegrateRefMapper.selectList(qw);
        List<String> myBindList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(refList)) {
            myBindList = refList.stream().map(ProgressIntegrateRef::getResourceId).collect(Collectors.toList());
        }
        return myBindList;
    }

    @Override
    public RestMessage importProgressTask(MultipartFile file, Long progressId) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        //获取当前时间的时间
        String formatter = DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN);
        String key = progressInfoKey + ":" + formatter;
        AsyncUtil.submitTask(key, () -> {
            ExcelResultDTO resultDTO;
            try {
                resultDTO = importProgressTaskExcel(file, tenantId, progressId);
            } catch (Exception e) {
                throw new BusinessException(e.getMessage());
            }
            return resultDTO;
        });
        return RestBuilders.successBuilder().data(key).build();
    }

    @Override
    public RestMessage pointMark(ProgressInfoVo progressInfoVo) {
        //查询
        Long id = progressInfoVo.getId();
        //进度信息
        ProgressInfo progressInfo = baseMapper.selectById(id);
        Assert.notNull(progressInfo, "数据不存在");

        //设置标记
        progressInfo.setPoint(progressInfoVo.getPoint());
        baseMapper.updateById(progressInfo);

        return RestBuilders.successBuilder().build();
    }

    @Override
    public IPage<ScreenProgressInfoDTO> screenProgressTaskInfo(Page page, ProgressInfoVo progressInfoVo) {
        LinkappUser linkappUser = linkappUserContextProducer.getCurrent();
        Assert.notNull(linkappUser, "用户登录信息为空");
        String tenantId = linkappUser.getTenantId();
        Assert.notNull(tenantId, "用户租户id为空");

        //查询进度总计划
        List<String> parentIds = new ArrayList<>();
        QueryWrapper<ProgressInfo> qw = new QueryWrapper<>();
        qw.eq("tenant_id_", tenantId);
        qw.eq("type_", 1);
        qw.eq("plan_type_", 1);
        List<ProgressInfo> planProgressList = baseMapper.selectList(qw);
        if (CollectionUtil.isNotEmpty(planProgressList)) {
            //planProgressList的parentIds拼接上id，组成List
            parentIds = planProgressList.stream().map(planProgress -> planProgress.getParentIds() + planProgress.getId() + ",").collect(Collectors.toList());
        }

        progressInfoVo.setParentIdsList(parentIds);

        IPage<ScreenProgressInfoDTO> iPage = baseMapper.screenProgressTaskInfo(page, progressInfoVo);

        return iPage;
    }

    /**
     * 导入进度任务Excel
     *
     * @param file       excel文件
     * @param tenantId   租户id
     * @param progressId 进度id
     * @return ExcelResultDTO
     */
    private ExcelResultDTO importProgressTaskExcel(MultipartFile file, String tenantId, Long progressId) {
        List<List<String>> excelList;
        excelList = ExcelReadUtil.getExcelInfo(file, 2, -1, -1);
        if (excelList.size() > 0 && excelList.get(0).size() < 6) {
            throw new BusinessException("模板错误,请选择正确的文件导入");
        }
        ExcelResultDTO excelResultDTO = getExcelResultDTO(excelList, tenantId, progressId);
        return excelResultDTO;
    }

    /**
     * 执行导入和验证
     *
     * @param excelList  excel数据
     * @param progressId
     * @return ExcelResultDTO
     */
    private ExcelResultDTO getExcelResultDTO(List<List<String>> excelList, String tenantId, Long progressId) {

        ExcelResultDTO excelResultDTO = new ExcelResultDTO();
        //正常导入数据
        List<ProgressInfo> progressInfoList = new ArrayList<>();
        //异常数据组织返回
        List<ExcelResultDetailDTO> excelResultDetailDTOS = new ArrayList<>();

        ProgressInfo parentProgress = baseMapper.selectById(progressId);
        Assert.notNull(parentProgress, "父级进度数据不存在");
        Map<String, ProgressInfo> parentMap = new HashMap<>();
        parentMap.put("0", parentProgress);
        for (int i = 0; i < excelList.size(); i++) {
            ExcelResultDetailDTO excelResultDetailDTO = new ExcelResultDetailDTO();
            excelResultDetailDTO.setNo(i + 3);
            //异常提示信息
            List<String> msgs = new ArrayList<>();
            List<String> list = excelList.get(i);
            //验证塞数据
            ProgressInfo progresstask = new ProgressInfo();
            //1进度，2任务
            progresstask.setType(2);
            progresstask.setTenantId(tenantId);

            String code = list.get(0).trim();
            if (StringUtils.isBlank(code)) {
                //excelResultDetailDTO.setDetail("大纲级别为空");
                msgs.add("大纲级别为空");
                //excelResultDetailDTOS.add(excelResultDetailDTO);
                //continue;
            }
            if ("1".equals(code)) {
                //父级归位
                parentMap.clear();
                parentMap.put("0", parentProgress);
            }

            progresstask.setName(checkValue(list.get(1).trim(), msgs, "任务名称", 10, true));
            String totalWorkStr = checkValue(list.get(2).trim(), msgs, "工期(天)", 10, true);
            if (StringUtils.isNotBlank(totalWorkStr)) {
                if (!NumberUtil.isNumber(totalWorkStr)) {
                    msgs.add("工期(天)不是数字");
                } else {
                    progresstask.setTotalWork(Integer.parseInt(totalWorkStr));
                }
            }
            String startTimeStr = checkValue(list.get(3).trim(), msgs, "计划开始", 10, true);
            ;
            if (StringUtils.isNotBlank(startTimeStr)) {
                Date time = parseStrToDateTime(startTimeStr, msgs);
                if (time != null) {
                    progresstask.setStartTime(time);
                }
            }
            String endTimeStr = checkValue(list.get(4).trim(), msgs, "计划结束", 10, true);
            ;
            if (StringUtils.isNotBlank(endTimeStr)) {
                Date time = parseStrToDateTime(endTimeStr, msgs);
                if (time != null) {
                    progresstask.setEndTime(time);
                }
            }
            String beforeWorkStr = list.get(5).trim();
            if (StringUtils.isNotBlank(beforeWorkStr)) {
                progresstask.setBeforeWork(beforeWorkStr);
            }

            //校验时间
            if (progresstask.getStartTime() != null && progresstask.getEndTime() != null) {
                Date startTime = progresstask.getStartTime();
                Date endTime = progresstask.getEndTime();
                if (DateUtil.isSameDay(startTime, endTime)) {
                    //正常
                    progresstask.setStartTime(DateUtil.beginOfDay(startTime));
                    progresstask.setEndTime(DateUtil.endOfDay(endTime));
                }
                if (progresstask.getStartTime().after(progresstask.getEndTime())) {
                    //excelResultDetailDTO.setDetail("开始时间不能晚于结束时间");
                    //excelResultDetailDTOS.add(excelResultDetailDTO);
                    msgs.add("开始时间不能晚于结束时间");
                    //continue;
                }
            }

            ProgressInfo tempParent = null;
            if ("1".equals(code)) {
                tempParent = parentMap.get("0");
            } else {
                int codeIndex = Integer.parseInt(code) - 1;
                tempParent = parentMap.get(String.valueOf(codeIndex));
            }

            if (tempParent == null) {
                //没有父级，没办法存下面的
                msgs.add("没有父级");
                //excelResultDetailDTOS.add(excelResultDetailDTO);
                //continue;
            } else {
                progresstask.setParentId(tempParent.getId());
                progresstask.setParentIds(tempParent.getParentIds() + tempParent.getId() + ",");
            }


            if (CollectionUtil.isNotEmpty(msgs)) {
                excelResultDetailDTO.setDetail(StringUtils.join(msgs, ","));
                excelResultDetailDTO.setType(1);
                excelResultDetailDTOS.add(excelResultDetailDTO);
                continue;
            }

            progresstask.setPoint(2);
            commonService.setCreateAndModifyInfo(progresstask);

            //校验重复
            ProgressInfo waitInsert = checkExist(progresstask);
            if (waitInsert == null) {
                //不存在，需要导入
                int num = baseMapper.insert(progresstask);
                if (num == 1) {
                    //成功
                    progressInfoList.add(progresstask);

                    //父级放到map里，方便下面取
                    parentMap.put(code, progresstask);

                    progressInfoList.add(progresstask);
                } else {
                    //失败
                    excelResultDetailDTO.setType(1);
                    excelResultDetailDTO.setDetail("导入失败");
                    excelResultDetailDTOS.add(excelResultDetailDTO);
                }
            } else {
                //存在
                //父级放到map里，方便下面取
                parentMap.put(code, waitInsert);
            }

        }
        //汇总
        excelResultDTO.setSum(excelList.size());
        //成功数据
        excelResultDTO.setSuccess(progressInfoList.size());
        List<ExcelResultDetailDTO> repeat = excelResultDetailDTOS.stream()
                .filter(e -> Integer.valueOf(2).equals(e.getType())).collect(Collectors.toList());
        //重复数据
        excelResultDTO.setRepeat(repeat.size());
        List<ExcelResultDetailDTO> fail = excelResultDetailDTOS.stream()
                .filter(e -> Integer.valueOf(1).equals(e.getType())).collect(Collectors.toList());
        //失败数据
        excelResultDTO.setFail(fail.size());
        //去掉类型为空的
        excelResultDetailDTOS.removeIf(e -> null == e.getType());
        excelResultDTO.setExcelResultDetailDTOS(excelResultDetailDTOS);

        return excelResultDTO;
    }

    /**
     * 时间格式转换与校验
     *
     * @param dateTimeStr 时间格式字符串
     * @param msgs        异常信息
     * @return 时间
     */
    private Date parseStrToDateTime(String dateTimeStr, List<String> msgs) {
        if (StringUtils.isNotBlank(dateTimeStr)) {
            dateTimeStr = dateTimeStr.replaceAll("年", "/").replaceAll("月", "/").replaceAll("日", "");
            if (dateTimeStr.contains("-")) {
                dateTimeStr = dateTimeStr.replaceAll("-", "/");
            }
        }
        Date time = null;
        try {
            String dateTimeStrArr[] = dateTimeStr.split(" ");
            String dateStr = dateTimeStrArr[0];
            String timeStr = null;
            if (dateTimeStrArr.length == 2) {
                timeStr = dateTimeStrArr[1];
            }

            String finalTimeStr = "";
            if (StringUtils.isNotBlank(dateStr)) {
                String dateStrArr[] = dateStr.split("/");
                if (dateStrArr.length != 3) {
                    msgs.add("时间格式错误");
                    return time;
                }
                String year = dateStrArr[0];
                String month = dateStrArr[1];
                String day = dateStrArr[2];
                if (month.length() == 1) {
                    month = "0" + month;
                }
                if (day.length() == 1) {
                    day = "0" + day;
                }
                finalTimeStr = year + "/" + month + "/" + day;
            }
            if (StringUtils.isNotBlank(timeStr)) {
                String timeStrArr[] = timeStr.split(":");
                if (timeStrArr.length != 3) {
                    msgs.add("时间格式错误");
                    return time;
                }
                String hour = timeStrArr[0];
                String minute = timeStrArr[1];
                String second = timeStrArr[2];
                if (hour.length() == 1) {
                    hour = "0" + hour;
                }
                if (minute.length() == 1) {
                    minute = "0" + minute;
                }
                if (second.length() == 1) {
                    second = "0" + second;
                }
                finalTimeStr = finalTimeStr + " " + hour + ":" + minute + ":" + second;
            }
            if (finalTimeStr.length() == 19) {
                time = DateUtil.parse(finalTimeStr, "yyyy/MM/dd HH:mm:ss");
            }
            if (finalTimeStr.length() == 10) {
                time = DateUtil.parse(finalTimeStr, "yyyy/MM/dd");
            }

        } catch (Exception e) {
            msgs.add("时间格式错误");
        } finally {
            return time;
        }
    }

    /**
     * 验证重复
     *
     * @param progressInfo 进度信息
     */
    private ProgressInfo checkExist(ProgressInfo progressInfo) {
        LambdaQueryWrapper<ProgressInfo> queryWrapper = new LambdaQueryWrapper<>();
        //设置判断重复条件
        queryWrapper.eq(ProgressInfo::getTenantId, progressInfo.getTenantId());
        queryWrapper.eq(ProgressInfo::getName, progressInfo.getName());
        queryWrapper.eq(ProgressInfo::getType, progressInfo.getType());
        queryWrapper.eq(ProgressInfo::getParentId, progressInfo.getParentId());
        //编辑的时候存在id
        Optional.ofNullable(progressInfo.getId()).ifPresent(id -> queryWrapper.ne(ProgressInfo::getId, progressInfo.getId()));
        ProgressInfo integer = baseMapper.selectOne(queryWrapper);
        return integer;
    }

    /**
     * 验证必填字段
     *
     * @param value 值
     * @param msgs  异常信息
     * @param flag  true验证非空 false 不验证非空
     * @return 返回值
     */
    private String checkValue(String value, List<String> msgs, String name, Integer num, Boolean flag) {
        if (StringUtils.isBlank(value)) {
            if (flag) {
                msgs.add(name + "为空");
            }
        } else if (value.length() > num) {
            msgs.add(name + "长度超出,字数限制" + num);
        }
        return value;
    }


    @Override
    public ProgressInfo getOneById(Serializable id) {
        return baseMapper.getOneById(id);
    }

    /**
     * 校验重复
     */
    private void validRepeat(ProgressInfo appProgressInfo) {
        QueryWrapper<ProgressInfo> qw = new QueryWrapper<>();
        if (appProgressInfo.getTenantId() != null) {
            qw.eq("tenant_id_", appProgressInfo.getTenantId());
        }
        qw.eq("name_", appProgressInfo.getName());
        qw.eq("type_", appProgressInfo.getType());
        if (appProgressInfo.getParentId() != null) {
            qw.eq("parent_id_", appProgressInfo.getParentId());
        }
        if (appProgressInfo.getId() != null) {
            qw.ne("id_", appProgressInfo.getId());
        }
        List<ProgressInfo> list = baseMapper.selectList(qw);
        if (list.size() > 0 && (list.size() > 1 || ObjectUtils.isEmpty(appProgressInfo.getId()) || !appProgressInfo.getId().equals(list.get(0).getId()))) {
            throw new BusinessException("名称重复");
        }
        Integer type = appProgressInfo.getType();
        //如果type=1，计划类型只能有一个总计划
        if (type == 1) {
            Integer planType = appProgressInfo.getPlanType();
            if (planType != null && planType == 1) {
                //总计划
                QueryWrapper<ProgressInfo> planQw = new QueryWrapper<>();
                planQw.eq("tenant_id_", appProgressInfo.getTenantId());
                planQw.eq("type_", 1);
                planQw.eq("plan_type_", 1);
                List<ProgressInfo> planList = baseMapper.selectList(planQw);
                if (!planList.isEmpty() && (planList.size() > 1 || ObjectUtils.isEmpty(appProgressInfo.getId()) || !appProgressInfo.getId().equals(planList.get(0).getId()))) {
                    throw new BusinessException("已有总计划，需在总计划上进行编辑");
                }
            }
        }

    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(ProgressInfo appProgressInfo) {
        Assert.notNull(appProgressInfo, "参数为空");
        Assert.notNull(appProgressInfo.getType(), "类型为空");
        Assert.isTrue(StringUtils.isNotBlank(appProgressInfo.getName()), "名称为空");
        Date startTime = appProgressInfo.getStartTime();
        Date endTime = appProgressInfo.getEndTime();
        if (startTime != null && endTime != null) {
            //开始时间、结束树间都不空才校验
            Assert.isTrue(startTime.before(endTime), "开始时间不能晚于结束时间");
        }
        Integer type = appProgressInfo.getType();
        //1计划，2任务
        if (type == 1) {
            Assert.isTrue(appProgressInfo.getPlanType() != null, "计划类型为空");
        }
        if (type == 2) {
            Assert.notNull(startTime, "计划开始时间为空");
            Assert.notNull(endTime, "计划结束时间为空");
            Assert.notNull(appProgressInfo.getTotalWork(), "工期为空");
        }
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(ProgressInfo appProgressInfo) {
        //Assert.isTrue(appProgressInfo.getName() == null || appProgressInfo.getName().length() <= 50,
        //        "名称超长");
    }
}

